﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Artemis.Core.Configuration;
using System.Data.Common;
using System.Threading;

namespace Artemis.Data.ProxyProvider {
    static class Helper {
        static int __count = 0;
        static Dictionary<string, List<string>> _readServers = new Dictionary<string, List<string>>();
        static Dictionary<string, List<string>> _writeServers = new Dictionary<string, List<string>>();

        static Helper() {
            Init();
        }

        static void Init() {
            string fileName = "artemis.config";
            string secionName = "artemis.Proxy";
            var file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
            ArtemisProxy section = null;

            if (File.Exists(file)) {
                var cfg = new Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource(file);
                section = cfg.GetSection(secionName) as ArtemisProxy;
            } else {
                section = System.Configuration.ConfigurationManager.GetSection(secionName) as ArtemisProxy;
            }

            foreach (ServerGroup group in section.ServerGroups) {
                var key = group.Name;
                List<string> servers = new List<string>();
                string writeConnectionString;
                foreach (Server item in group) {
                    if (item.Mode == "read") {
                        servers.Add(item.ConnectionString);
                    } else {
                        if (_writeServers.ContainsKey(key))
                            throw new ArgumentException("write server has been added.");
                        writeConnectionString = item.ConnectionString;
                        _writeServers.Add(key, new List<string>() { item.ConnectionString });
                    }
                }
                if (servers.Count == 0)
                    throw new ArgumentNullException("read server count is 0.");
                _readServers.Add(key, servers);
            }
        }

        public static void OpenConnection(this ProxyConnection conection, ProxyCommandDefinition definition) {
            if (conection.WrappedConnection.State != System.Data.ConnectionState.Closed)
                return;
            string connectionString = string.Empty;// conection.ActualConnection.ConnectionString;
            if (conection.ServerGroupName != string.Empty) {
                if (!definition.IsReadOnly) {
                    if (_writeServers.ContainsKey(conection.ServerGroupName))
                        connectionString = _writeServers[conection.ServerGroupName].FirstOrDefault();
                    if (string.IsNullOrEmpty(connectionString))
                        throw new ArgumentNullException("could not find group:" + conection.ServerGroupName);
                } else {
                    if (!_readServers.ContainsKey(conection.ServerGroupName))
                        throw new ArgumentNullException("could not find group:" + conection.ServerGroupName);
                    var lst = _readServers[conection.ServerGroupName];
                    var index = Interlocked.Increment(ref __count) % lst.Count;
                    connectionString = lst[index];

                }
            }

            conection.ActualConnection.ConnectionString = connectionString;// conection.ActualConnection.ConnectionString.Replace("{" + conection.ServerGroupName + "}", connectionString);
            conection.OpenWrappedConnection();
            //if(!definition.IsReadOnly)
            //    return _writeServers.
        }
    }


}
